home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_08_03 / 8n03110a < prev    next >
Text File  |  1990-03-18  |  5KB  |  259 lines

  1. *****Listing 3*****
  2.  
  3. // LIST.CPP - implementation of non-specific double linked lists
  4.  
  5. #include <stream.hpp>
  6. #include <stddef.h>
  7. #include <string.h>
  8. #include "list.hpp"
  9.  
  10. LIST::LIST()      // constructor
  11.    {
  12.    head = curr = tail = NULL;
  13.    }
  14.  
  15. LIST::~LIST()     // destructor
  16.    {
  17.    struct listelem *work;
  18.  
  19.    while(head != NULL)
  20.       {
  21.       delete_data(head);
  22.       work = head->next;
  23.       delete head;
  24.       head = work;
  25.       }
  26.    }
  27.  
  28. void *LIST::get_head(unsigned int &sz)
  29.    {
  30.    curr = head;
  31.    return get_curr(sz);
  32.    }
  33.  
  34. void *LIST::get_curr(unsigned int &sz)
  35.    {
  36.    if(curr == NULL)
  37.       {
  38.       sz = 0;
  39.       return NULL;
  40.       }
  41.    sz = curr->size;
  42.    return curr->data;
  43.    }
  44.  
  45. void *LIST::get_tail(unsigned int &sz)
  46.    {
  47.    curr = tail;
  48.    return get_curr(sz);
  49.    }
  50.  
  51. void *LIST::get_prev(unsigned int &sz)
  52.    {
  53.    if(curr->prev != NULL)
  54.       {
  55.       curr = curr->prev;
  56.       return get_curr(sz);
  57.       }
  58.    else
  59.       {
  60.       sz = 0;
  61.       return NULL;
  62.       }
  63.    }
  64.  
  65. void *LIST::get_next(unsigned int &sz)
  66.    {
  67.    if(curr->next != NULL)
  68.       {
  69.       curr = curr->next;
  70.       return get_curr(sz);
  71.       }
  72.    else
  73.       {
  74.       sz = 0;
  75.       return NULL;
  76.       }
  77.    }
  78.  
  79. void LIST::add_before(void *vptr, unsigned int sz)
  80.    {
  81.    struct listelem *lptr;
  82.  
  83.    lptr = new struct listelem;
  84.    if(lptr == NULL)
  85.       exit(99);         // ugly - should be fixed later
  86.  
  87.    lptr->size = sz;
  88.    create_data(lptr);
  89.    copy_data(lptr,vptr);
  90.  
  91.    // rearrange pointers
  92.  
  93.    if(curr != NULL)
  94.       {
  95.       lptr->prev = curr->prev;
  96.       lptr->next = curr;
  97.  
  98.       if(lptr->prev != NULL)
  99.          lptr->prev->next = lptr;
  100.       else
  101.          head = lptr;
  102.  
  103.       curr->prev = lptr;
  104.       }
  105.    else     // curr == NULL - must be first element in list
  106.       {
  107.       lptr->prev = lptr->next = NULL;
  108.       head = curr = tail = lptr;
  109.       }
  110.    }
  111.  
  112. void LIST::add_after(void *vptr, unsigned int sz)
  113.    {
  114.    struct listelem *lptr;
  115.  
  116.    lptr = new struct listelem;
  117.    if(lptr == NULL)
  118.       exit(99);         // ugly - should be fixed later
  119.  
  120.    lptr->size = sz;
  121.    create_data(lptr);
  122.    copy_data(lptr,vptr);
  123.  
  124.    // rearrange pointers
  125.  
  126.    if(curr != NULL)
  127.       {
  128.       lptr->prev = curr;
  129.       lptr->next = curr->next;
  130.  
  131.       curr->next = lptr;
  132.  
  133.       if(lptr->next != NULL)
  134.          lptr->next->prev = lptr;
  135.       else
  136.          tail = lptr;
  137.       }
  138.    else     // curr == NULL - must be first element in list
  139.       {
  140.       lptr->prev = lptr->next = NULL;
  141.       head = curr = tail = lptr;
  142.       }
  143.    }
  144.  
  145. void LIST::add_head(void *vptr, unsigned int sz)
  146.    {
  147.    struct listelem *lptr;
  148.  
  149.    lptr = new struct listelem;
  150.    if(lptr == NULL)
  151.       exit(99);         // ugly - should be fixed later
  152.  
  153.    lptr->size = sz;
  154.    create_data(lptr);
  155.    copy_data(lptr,vptr);
  156.  
  157.    if(head != NULL)
  158.       {
  159.       lptr->prev = NULL;
  160.       lptr->next = head;
  161.       head->prev = lptr;
  162.       head = lptr;
  163.       }
  164.    else
  165.       {
  166.       lptr->prev = lptr->next = NULL;
  167.       head = curr = tail = lptr;
  168.       }
  169.    }
  170.  
  171. void LIST::add_tail(void *vptr, unsigned int sz)
  172.    {
  173.    struct listelem *lptr;
  174.  
  175.    lptr = new struct listelem;
  176.    if(lptr == NULL)
  177.       exit(99);         // ugly - should be fixed later
  178.  
  179.    lptr->size = sz;
  180.    create_data(lptr);
  181.    copy_data(lptr,vptr);
  182.  
  183.    if(tail != NULL)
  184.       {
  185.       lptr->next = NULL;
  186.       lptr->prev = tail;
  187.       tail->next = lptr;
  188.       tail = lptr;
  189.       }
  190.    else
  191.       {
  192.       lptr->prev = lptr->next = NULL;
  193.       head = curr = tail = lptr;
  194.       }
  195.    }
  196.  
  197. void LIST::delete_curr()
  198.    {
  199.    struct listelem *lptr;
  200.  
  201.    if(curr == NULL)
  202.       return;
  203.  
  204.    lptr = curr;
  205.  
  206.    if(curr->prev != NULL)
  207.       curr->prev->next = curr->next;
  208.    else
  209.       head = curr->next;
  210.  
  211.    if(curr->next != NULL)
  212.       curr->next->prev = curr->prev;
  213.    else
  214.       tail = curr->prev;
  215.  
  216.    if(curr->prev != NULL)
  217.       curr = curr->prev;
  218.    else if(curr->next != NULL)
  219.       curr = curr->next;
  220.    else if(head == NULL && tail == NULL)
  221.       curr = NULL;      // list is now empty
  222.    else
  223.       {
  224.       cerr << "LIST::delete_curr() : deletion sequence error\n";
  225.       exit(99);
  226.       }
  227.  
  228.    delete_data(lptr);
  229.    delete lptr;
  230.    }
  231.  
  232. // The following three functions should be replaced in all derived classes.
  233. // create_data() should allocate and initialize space for a new instance of
  234. // the class being stored in the list (implying that you should derive a new
  235. // class for each type of object).  delete_data() should handle the destruction
  236. // of class instances stored in a list.  copy_data() must take care of copying 
  237. // a complete class instance from one place to another - it must properly 
  238. // handle the situation where a class being stored in a list has 
  239. // dynamically-allocated storage.  As written these functions should properly 
  240. // handle all simple types (that is, types which have no dynamic storage). 
  241.  
  242. void LIST::create_data(struct listelem *lptr)
  243.    {
  244.    lptr->data = new char[lptr->size];
  245.    if(lptr->data == NULL)
  246.       exit(99);
  247.    }
  248.  
  249. void LIST::delete_data(struct listelem *lptr)
  250.    {
  251.    if(lptr->data != NULL)
  252.       delete lptr->data;
  253.    }
  254.  
  255. void LIST::copy_data(struct listelem *lptr, void *from)
  256.    {
  257.    memcpy(lptr->data,from,lptr->size);
  258.    }
  259.